package com.newlink.building.userinfo

import android.Manifest
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.bluetooth.BluetoothGattCharacteristic
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import cn.com.heaton.blelibrary.ble.Ble
import cn.com.heaton.blelibrary.ble.BleLog
import cn.com.heaton.blelibrary.ble.callback.BleConnectCallback
import cn.com.heaton.blelibrary.ble.callback.BleNotifyCallback
import cn.com.heaton.blelibrary.ble.callback.BleScanCallback
import cn.com.heaton.blelibrary.ble.callback.BleWriteCallback
import cn.com.heaton.blelibrary.ble.model.BleDevice
import cn.com.heaton.blelibrary.ble.utils.ByteUtils
import com.newlink.building.common_base.base.BaseApplication
import com.newlink.building.common_base.constant.Base_Constant
import com.newlink.building.common_base.constant.Base_Constant.BLE_OPEN_DOOR_NAME
import com.newlink.building.common_base.event.MessageEvent
import com.newlink.building.common_base.event.TYPE_APP_BLE_OPEN_DOOR_RESULT
import com.newlink.building.common_base.event.TYPE_APP_OPEN_BT
import com.newlink.building.common_base.event.TYPE_APP_SHOW_WAITING_DIALOG
import com.newlink.building.common_base.ext.showToastLong
import com.newlink.building.common_base.fastble.utils.Base_HexUtil
import com.newlink.building.common_base.utils.NLog
import com.newlink.building.common_base.utils.Base_Preference
import com.newlink.building.common_base.utils.ShakeManager
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationHelper
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationInvoker
import com.newlink.building.userinfo.activity.Module_UserInfo_AuthManageActivityNL
import com.newlink.building.userinfo.bean.Module_UserInfo_FvlBleDoorDevice
import com.newlink.building.userinfo.ble.Module_UserInfo_MyBleWrapperCallback
import com.newlink.building.userinfo.utils.Module_UserInfo_BtByteUtils
import com.newlink.building.userinfo.utils.doCryptWork
import com.newlink.building.userinfo.utils.getSecondTimestampTwo
import com.newlink.building.userinfo.utils.padWithZeros
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import java.util.*


/**
 * @Author: Jake
 * @Date: 2024-03-27
 * @Description:
 */
class Module_UserInfo_BtOpenDoorService2 : Service() {

    companion object {
        const val SERVICE_START: String = "com.newlink.building.userinfo.action.SERVICE_START"
        const val SERVICE_STOP: String = "com.newlink.building.userinfo.action.SERVICE_STOP"
        const val SERVICE_UPDATE_SHAKE_LEVEL: String =
            "com.newlink.building.userinfo.action.UPDATE_SHAKE_LEVEL"
        const val SEND_OPEN_DOOR_ACTION: String =
            "com.newlink.building.userinfo.action.SEND_OPEN_DOOR_ACTION"

        private const val NOTIFICATION_CHANNEL_ID = "CHANNEL_ID"
        private const val NOTIFICATION_CHANNEL_NAME = "CHANNEL_NAME"
        private const val FOREGROUND_ID: Int = 1_001_002

        private const val TAG = "fvl_BT2"
        private const val CRYPT_KEY = "9EF57D1FA4C32459B1675AE83C049B18"

        var useBluetooth: Boolean by Base_Preference(Base_Constant.BT_OPEN_DOOR_KEY, false)
        var lastBleAddr: String by Base_Preference(Base_Constant.BT_OPEN_DOOR_LAST_ADDR, "")

        const val SERVICE_UUID = "55535343-fe7d-4ae5-8fa9-9fafd205e455"
        const val CHARACTERISTIC_WRITE_UUID = "49535343-8841-43f4-a8d4-ecbe34729bb3"
        const val CHARACTERISTIC_NOTIFY_UUID = "49535343-1e4d-4bd9-ba61-23c647249616"

        @RequiresApi(Build.VERSION_CODES.S)
        private val BLUETOOTH_PERMISSIONS_S = arrayOf(
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )

        private val BLUETOOTH_PERMISSIONS = arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    }

    private var userId: Long by Base_Preference(Base_Constant.USER_ID_KEY, 0L)
    private var notificationManager: NotificationManager? = null
    private var notification: Notification? = null
    private var notificationChannel: NotificationChannel? = null
    private var mShakeManager: ShakeManager? = null
    private lateinit var mBle: Ble<BleDevice>
    private var mLastSendTime: Long = 0

    private var mCurrentDevice: BleDevice? = null
    private var fvlDeviceList = mutableListOf<Module_UserInfo_FvlBleDoorDevice>()
    private val mHandler by lazy {
        Handler(Looper.getMainLooper())
    }

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 蓝牙开门服务启动时的混淆
        Module_Obfuscation_ObfuscationHelper.onMethodEnter("BtOpenDoorService2", "onStartCommand")
        Module_Obfuscation_ObfuscationInvoker.invokeRandom(intent?.action?.hashCode() ?: System.currentTimeMillis())

        val action = intent?.action
        Log.e(TAG, "========BtOpenDoorService1 onStartCommand ======== $action")
        when (action) {
            SERVICE_START -> {
                Module_Obfuscation_ObfuscationInvoker.invokeSpecific(7, "SERVICE_START")
                initBLE()
                warmUpBle()
                watchShake2()
            }


            SERVICE_UPDATE_SHAKE_LEVEL -> {
                Module_Obfuscation_ObfuscationInvoker.invokeSpecific(8, "UPDATE_SHAKE")
                initBLE()
                updateShake()
            }
        }

        return START_STICKY
    }

    private fun warmUpBle() {
        if (!::mBle.isInitialized) {
            return
        }
        NLog.e("[OpenDoorService2] >> warm ----------- ${mBle.isBleEnable}")
        if (mBle.isBleEnable && !isBleWorking && hasBluetoothPermissions()) {
            isBleWorking = true
            NLog.e("[OpenDoorService2] >> scan test warm -----------")
            mBle.startScan(object : BleScanCallback<BleDevice>() {
                override fun onLeScan(
                    device: BleDevice?,
                    rssi: Int,
                    scanRecord: ByteArray?,
                ) {
                }

                override fun onStop() {
                    super.onStop()
                    NLog.e("[OpenDoorService2] >> scan test end --------------")
                    isBleWorking = false
                }

            }, 800)
        }
    }

    private fun updateShake() {
        NLog.e("updateShake")
        mShakeManager?.releaseShake()
        mShakeManager = null
        watchShake2()
    }

    private fun initBLE() {
        // 初始化蓝牙时的混淆
        Module_Obfuscation_ObfuscationHelper.beforeNetworkRequest("BLE", mapOf("init" to userId))
        Module_Obfuscation_ObfuscationInvoker.invokeRandom(userId)

        mBle = Ble.options().apply {
            logBleEnable = true
            throwBleException = true
            autoConnect = true
            connectFailedRetryCount = 2
            connectTimeout = 6000L
            scanPeriod = 3300L
            uuidService = UUID.fromString(SERVICE_UUID)
            uuidWriteCha = UUID.fromString(CHARACTERISTIC_WRITE_UUID)
            bleWrapperCallback = Module_UserInfo_MyBleWrapperCallback()
        }.create(applicationContext, object : Ble.InitCallback {
            override fun failed(failedCode: Int) {
                BleLog.i(TAG, "init failed: $failedCode")
            }

            override fun success() {
                BleLog.i(TAG, "init success")
            }

        })
    }


    @SuppressLint("WrongConstant")
    private fun stopService() {
        Log.e(TAG, "stop_bt_open_door_service")
        mBle.stopScan()
        mBle.released()

        if (mShakeManager != null) {
            Log.e(TAG, "RELEASE SHAKE LISTENER")
            mShakeManager?.releaseShake()
            mShakeManager = null
        }

    }

    private fun startBtForegroundService() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationChannel = NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL_NAME,
                NotificationManager.IMPORTANCE_HIGH
            )
            notificationChannel?.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            notificationManager?.createNotificationChannel(notificationChannel!!)
        }
        val notificationIntent = Intent(this, Module_UserInfo_AuthManageActivityNL::class.java)
        val pendingIntent =
            PendingIntent.getService(
                this,
                0,
                notificationIntent,
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notification = Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setSmallIcon(android.R.mipmap.sym_def_app_icon)
                .setContentTitle("Fanvil Link")
                .setContentText("Fanvil link 蓝牙开门服务")
                .setContentIntent(pendingIntent)
                .build()
        }
        //        notification?.flags = notification?.flags or Notification.FLAG_NO_CLEAR
        startForeground(FOREGROUND_ID, notification)
    }

    private fun watchShake2() {
//        mShakeManager = ShakeManager(this@BtOpenDoorService2, isOpenVibrator = true)
        if (mShakeManager == null) {
            mShakeManager = ShakeManager.getInstance(BaseApplication.context)
            mShakeManager?.initShakeParam()
            NLog.e("[BLE] mShakeManager init  :: $mShakeManager ")
            val app = application as BaseApplication
            mShakeManager?.setOnShakeListener(object : ShakeManager.OnShakeListener {
                override fun onShake(isSuccess: Boolean) {
                    if (isSuccess) {
                        NLog.e("[BLE] onShake success ")
                        if (isBleWorking) {
                            NLog.e("[BLE] onShake .. too much , please wait.. ")
                            return
                        }

                        NLog.e("[BLE] onShake .. app foreground = ${app.isAppForeground}")
                        if (!app.isAppForeground) {
                            return
                        }

                        if (!mBle.isSupportBle(this@Module_UserInfo_BtOpenDoorService2)) {
                            return
                        }

                        if (hasBluetoothPermissions()) {
                            NLog.e("[BLE] =======================${mBle.isBleEnable}")
                            if (!mBle.isBleEnable) {
                                NLog.e("[BLE] =======================")
//                                mBle.toggleBluetooth(true)
                                EventBus.getDefault()
                                    .post(MessageEvent(TYPE_APP_OPEN_BT, 1))
                                return
                            }

                            if (isBleWorking) {
                                return
                            }
                            NLog.e("have permission")

//                            isBleWorking = true
//                            doScanBleDevice()
                            if (false && lastBleAddr.isNotEmpty()) {
                                useLast = true
                                NLog.e("[BLE] >>>  use last")
                                mBle.connect(lastBleAddr, connectCallback())
                                EventBus.getDefault()
                                    .post(MessageEvent(TYPE_APP_SHOW_WAITING_DIALOG, 1))
                            } else {
                                isBleWorking = true
                                NLog.e("[BLE] >>>  do Scan start")
                                useLast = false
                                doScanBleDevice()
                            }
                        } else {
                            // Stop the service if permissions are not granted
                            NLog.e("has not permission")
                            showToastLong(getString(R.string.no_bt_premission))
                            sendBroadcast(Intent(Base_Constant.ACTION_REQUEST_BLE_PERMISSION))
                            useBluetooth = false
                            stopSelf()
                        }
                    }
                }
            })
        }
    }


    private fun bleScanCallback(): BleScanCallback<BleDevice> {
        return object : BleScanCallback<BleDevice>() {
            override fun onStart() {
                super.onStart()
                NLog.e("BLE SCAN >>  onStart")
                EventBus.getDefault()
                    .post(MessageEvent(TYPE_APP_SHOW_WAITING_DIALOG, 1))
            }

            override fun onLeScan(device: BleDevice?, rssi: Int, scanRecord: ByteArray?) {
                device?.let {
                    if (TextUtils.isEmpty(it.bleName) || rssi < -86) {
                        return
                    }
//                    NLog.e("BLE SCAN >>  onLeScan -> ${it.bleName} : $rssi")
                    if (it.bleName.contains(BLE_OPEN_DOOR_NAME)) {
                        foundTarget = true
                        updateNotificationInfo("★ Find target >>> ${it.bleName} >> mac :${it.bleAddress} >> rssi : $rssi ")
                        if (rssi >= -70) {
                            isConnecting = true
                            mBle.stopScan()
                            doConnect(it)
                            return
                        }

                        if (!checkRepeatDevice(it)) {
                            fvlDeviceList.add(Module_UserInfo_FvlBleDoorDevice(it, rssi))
                        }
                    }
                }
            }

            override fun onStop() {
                super.onStop()
                NLog.e("BLE SCAN >>  onStop")
                if (!foundTarget) {
                    if (isBleWorking) {
                        showBleActionResult("No device found\nPlease retry")
                        resetBleManager()
                    }
                } else {
                    if (isConnecting) {
                        return
                    }
                    updateNotificationInfo("======  发现${fvlDeviceList.size}个设备 ====== ")

                    val maxRssiDevice = fvlDeviceList.maxByOrNull { it.rssi }
                    updateNotificationInfo("Signal Max RSSI：${maxRssiDevice?.device?.bleAddress}")
                    maxRssiDevice?.let {
                        updateNotificationInfo(" ready start connect .....")
                        doConnect(it.device)
                    }
                }
            }
        }
    }

    private fun doConnect(device: BleDevice) {
        // 连接蓝牙设备时的混淆
        Module_Obfuscation_ObfuscationHelper.beforeNetworkRequest("BLE", mapOf("bleAddress" to device.bleAddress))
        Module_Obfuscation_ObfuscationInvoker.invokeSpecific(15, mapOf("bleName" to device.bleName))

        device.apply {
            NLog.e("[BtOpenDoorService2] >> doConnect  >> isConnect : $isConnected")
            if (isConnected) {
                mBle.disconnect(this)
            } else {
                mHandler.postDelayed({
                    NLog.e("[BtOpenDoorService2] >> doConnect Start ==========")
                    mBle.connect(this, connectCallback())
                }, 402)
            }
        }
    }


    private fun hasBluetoothPermissions(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            BLUETOOTH_PERMISSIONS_S.all {
                ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
            }
        } else {
            BLUETOOTH_PERMISSIONS.all {
                ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
            }
        }

    }

    private var failedTime = 0

    private fun connectCallback(): BleConnectCallback<BleDevice> {
        return object : BleConnectCallback<BleDevice>() {
            override fun onConnectionChanged(device: BleDevice?) {
                NLog.e("BLE CONNECT >>  onConnectionChanged -> ${device?.bleName} : ${device?.bleAddress} : ${device?.isConnected}")
                if (!isBleWorking) {
                    if (mBle != null && device != null) {
                        mBle.disconnect(device)
                        resetBleManager()
                    }
                    return
                }
            }

            override fun onReady(device: BleDevice?) {
                super.onReady(device)
                NLog.e("BLE CONNECT >>  onReady -> ${device?.bleName} : ${device?.bleAddress}")
                mCurrentDevice = device
                mBle.enableNotify(device, true, bleNotifyCallback())
            }

            override fun onConnectCancel(device: BleDevice?) {
                super.onConnectCancel(device)
                NLog.e("BLE CONNECT >> onConnectCancel")
                showBleActionResult("Connect Cancel")
                resetBleManager()
            }

            override fun onConnectFailed(device: BleDevice?, errorCode: Int) {
                super.onConnectFailed(device, errorCode)
                NLog.e("BLE CONNECT >> onConnectFailed > errorCode : $errorCode")

                if (!isBleWorking) {
                    if (mBle != null && device != null) {
                        mBle.disconnect(device)
                        resetBleManager()
                    }
                    return
                }

                failedTime++
                NLog.e("BLE CONNECT >> onConnectFailed > time : $failedTime")

                if (failedTime == 2) {
                    if (useLast) {
                        NLog.e("BLE Connect >> use last failed research")
                        doScanBleDevice()
                    } else {
                        NLog.e("BLE CONNECT >> Can not connect : $failedTime : $errorCode")
                        showBleActionResult("Connect Failed")
                        resetBleManager()
                    }
                }


            }
        }
    }

    private fun bleNotifyCallback(): BleNotifyCallback<BleDevice> {
        return object : BleNotifyCallback<BleDevice>() {
            override fun onChanged(
                device: BleDevice?,
                characteristic: BluetoothGattCharacteristic?,
            ) {
                NLog.e(
                    "BLE Notify >> onChanged 收到硬件数据 -> ${
                        ByteUtils.toHexString(
                            characteristic?.value
                        )
                    } time : ${System.currentTimeMillis() / 1000}"
                )
                device?.let {
                    NLog.e(
                        "BLE Notify >> 回复设备端已经收到设备的开门结果"
                    )
                    sendBleMsgToDevice(it, "010101")
                }

                val s: String = Module_UserInfo_BtByteUtils.bytes2HexStr(characteristic?.value)
                val result = if (s == "0101") {
                    lastBleAddr = device?.bleAddress!!
                    showBleActionResult("1")
                    getString(com.newlink.building.userinfo.R.string.result_success)
                } else {
                    showBleActionResult("Device return failed : $s")
                    getString(com.newlink.building.userinfo.R.string.result_failure)
                }
                updateNotificationInfo("Ble door open result is $result", true)

                MainScope().launch {
                    delay(100)
                    disConnectDevice(device)
                }
            }

            override fun onNotifySuccess(device: BleDevice?) {
                super.onNotifySuccess(device)
                NLog.e("BLE Notify >>  onNotifySuccess -> ${device?.bleName} time : ${System.currentTimeMillis() / 1000}")
                MainScope().launch {
                    delay(250)
                    updateNotificationInfo("准备执行开门指令...", true)
                    val currentTime = getSecondTimestampTwo(Date())
                    val content = prepareOpenDoorContent(userId, currentTime)
                    updateNotificationInfo("开门指令内容...$content >> 内容长度: ${content.length}")
                    sendBleMsgToDevice(device!!, content)
                }
            }

            override fun onNotifyFailed(device: BleDevice?, failedCode: Int) {
                super.onNotifyFailed(device, failedCode)
                NLog.e("BLE Notify >>  onNotifyFailed -> $failedCode time : ${System.currentTimeMillis() / 1000}")
                resetBleManager()
            }
        }
    }

    private fun sendBleMsgToDevice(device: BleDevice, content: String) {
        // 发送蓝牙消息时的混淆
        Module_Obfuscation_ObfuscationHelper.beforeDatabaseOperation("BLE_MSG", content)
        Module_Obfuscation_ObfuscationInvoker.invokeRandom(content.hashCode())

        mBle.writeByUuid(
            device,
            Base_HexUtil.hexStringToBytes(content),
            UUID.fromString(SERVICE_UUID),
            UUID.fromString(CHARACTERISTIC_WRITE_UUID),
            object : BleWriteCallback<BleDevice>() {
                override fun onWriteSuccess(
                    device: BleDevice?,
                    characteristic: BluetoothGattCharacteristic?,
                ) {
                    updateNotificationInfo("写入指令成功长度...${characteristic?.value?.size} time : ${System.currentTimeMillis() / 1000}")
                    mHandler.postDelayed(
                        forceStopTaskRunnable, 2000
                    )
                }
            }
        )

    }


    private val forceStopTaskRunnable = Runnable {
        updateNotificationInfo("force stop ble action !!!")
        if (isBleWorking) {
            updateNotificationInfo("容错模式，写入成功,但是没有收到回调")
            resetBleManager()
        }
    }


    fun resetBleManager() {
        NLog.e(">>>>>>>>> resetBleManager >>>>>>>>>>>>")
//        Log.i("fvl" , "fvl >>> [BLE] do.reset" , Exception())
        isBleWorking = false
        isConnecting = false
        foundTarget = false
        useLast = false
        failedTime = 0

        mHandler.removeCallbacks(forceStopTaskRunnable)

        if (mCurrentDevice != null) {
            NLog.e(">>>> reset <<<< currentDevice : ${mCurrentDevice!!.bleAddress}")
            if (::mBle.isInitialized) {
                mBle.stopScan()
                NLog.e(">>>> reset <<<< currentDevice : ${mCurrentDevice!!.bleAddress} ok")
                mBle.disconnect(mCurrentDevice)
            }
            mCurrentDevice = null
        } else {
            NLog.e(">>>> reset <<<< disconnect all")
            if (::mBle.isInitialized) {
                mBle.stopScan()
                NLog.e(">>>> reset <<<< disconnect all ok")
                mBle.disconnectAll()
            }

        }
        fvlDeviceList.clear()
        EventBus.getDefault().post(MessageEvent(TYPE_APP_SHOW_WAITING_DIALOG, 0))
    }

    @SuppressLint("MissingPermission")
    private fun doScanBleDevice() {
//        if (isBleWorking) {
//            return
//        }
        try {
            mBle.startScan(bleScanCallback())
        } catch (e: Exception) {
            NLog.e("BLE Scan >>  doScanBleDevice Error >> $e")
            resetBleManager()
        }
    }


    private fun disConnectDevice(bleDevice: BleDevice?) {
        mBle.disconnect(bleDevice)
        resetBleManager()
    }


    /**
     * 准备开门数据
     * @param userId Long
     * @param currentTimeUnix String
     * @return String
     */
    private fun prepareOpenDoorContent(userId: Long, currentTimeUnix: String): String {
        // 准备开门数据时的安全混淆
        Module_Obfuscation_ObfuscationHelper.onMethodEnter("BtOpenDoorService2", "prepareOpenDoorContent")
        Module_Obfuscation_ObfuscationInvoker.invokeSpecific(19, userId)

        updateNotificationInfo("准备数据:: userId > $userId && currentTime > $currentTimeUnix")
        val currentTime = padWithZeros(currentTimeUnix, 16)
        val userIdByteArray = com.newlink.building.userinfo.utils.longToByteArray(userId)
        NLog.e(
            "userID  转为字节数组 ->  $userIdByteArray 长度是:${userIdByteArray.length}"
        )
        updateNotificationInfo("userID转字节数组 ->  $userIdByteArray 长度是:${userIdByteArray.length}")
        val text2 = "$userIdByteArray$currentTime"
        NLog.e(
            "userID字节数组+当前时间 ->  $text2  长度是:${text2.length}"
        )
        updateNotificationInfo("userID字节数组+当前时间 ->  $text2  长度是:${text2.length}")
        val content = doCryptWork(text2, CRYPT_KEY)
        NLog.e("★ CRC加密后的结果 ->  $content ")
        updateNotificationInfo("★ CRC加密后的结果 ->  $content   长度是:${content.length}")
        return content
    }

    private fun updateNotificationInfo(notification: String, debugShow: Boolean = true) {
        NLog.e("[BLE] >> $notification")
    }

    private fun showBleActionResult(result: String) {
        NLog.e("[BLE] >> 显示结果:  $result")
//        Log.i("fvl", "[BLE] >> showBleActionResult $result" , Exception())
        EventBus.getDefault().post(MessageEvent(TYPE_APP_BLE_OPEN_DOOR_RESULT, result))
    }

    @SuppressLint("WrongConstant")
    @RequiresApi(Build.VERSION_CODES.N)
    override fun onDestroy() {
        super.onDestroy()
        Log.e(TAG, "-----BtOpenDoorService2 service onDestroy-----")
        resetBleManager()
        stopService()
//        stopForeground(FOREGROUND_ID)
    }

    private fun checkRepeatDevice(device: BleDevice): Boolean {
        for (item in fvlDeviceList) {
            if (device.bleAddress.equals(item.device.bleAddress)) {
                return true
            }
        }
        return false
    }

    private var isBleWorking = false
    private var useLast = false
    private var foundTarget = false
    private var isConnecting = false

}